﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MeTV
{
    class Player
    {
        IntPtr vlcInstance = IntPtr.Zero;
        IntPtr vlcPlayer = IntPtr.Zero;

        class LibVlc
        {
            #region libvlc.h

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern string libvlc_errmsg();

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_clearerr();

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_new(int argc, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] argv);

            #endregion

            #region libvlc_media.h

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_new_location(IntPtr p_instance, [MarshalAs(UnmanagedType.LPStr)] string psz_mrl);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_new_path(IntPtr p_instance, [MarshalAs(UnmanagedType.LPStr)] string psz_mrl);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_new_as_node(IntPtr p_instance, [MarshalAs(UnmanagedType.LPStr)] string psz_mrl);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_add_option(IntPtr libvlc_media_inst, [MarshalAs(UnmanagedType.LPStr)] string ppsz_options);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_add_option_flag(IntPtr p_md, [MarshalAs(UnmanagedType.LPStr)] string ppsz_options, int i_flags);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_retain(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_release(IntPtr libvlc_media_inst);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            [return: MarshalAs(UnmanagedType.AnsiBStr)]
            public static extern string libvlc_media_get_mrl(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_duplicate(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_event_manager(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern Int64 libvlc_media_get_duration(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_parse(IntPtr media);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_parse_async(IntPtr media);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern int libvlc_media_is_parsed(IntPtr p_md);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_set_user_data(IntPtr p_md, IntPtr p_new_user_data);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_get_user_data(IntPtr p_md);

            #endregion

            #region libvlc_media_player.h

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_player_new(IntPtr p_libvlc_instance);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_player_new_from_media(IntPtr libvlc_media);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_release(IntPtr libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_retain(IntPtr p_mi);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_player_get_media(IntPtr libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_set_media(IntPtr libvlc_media_player_t, IntPtr libvlc_media_t);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_player_event_manager(IntPtr libvlc_media_player_t);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern int libvlc_media_player_is_playing(IntPtr p_mi);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_play(IntPtr libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_set_pause(IntPtr mp, int do_pause);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_pause(IntPtr libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_stop(IntPtr libvlc_mediaplayer);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern void libvlc_media_player_set_hwnd(IntPtr libvlc_mediaplayer, IntPtr libvlc_drawable);

            [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl)]
            public static extern IntPtr libvlc_media_player_get_hwnd(IntPtr libvlc_mediaplayer);

            #endregion
        }

        public Player()
        {
            vlcInstance = LibVlc.libvlc_new(0, null);
            vlcPlayer = LibVlc.libvlc_media_player_new(vlcInstance);
        }

        public void SetWindowHandle(Control control)
        {
            LibVlc.libvlc_media_player_set_hwnd(vlcPlayer, control.Handle);
        }

        public void Play(string mrl)
        {
            IntPtr media = LibVlc.libvlc_media_new_path(vlcInstance, mrl);
            LibVlc.libvlc_media_player_set_media(vlcPlayer, media);
            LibVlc.libvlc_media_release(media);
            LibVlc.libvlc_media_player_play(vlcPlayer);
        }

        public void Stop()
        {
            LibVlc.libvlc_media_player_stop(vlcPlayer);
        }
    }
}
